package com.hulk.dryad.admin.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hulk.dryad.admin.api.vo.SysTenantVO;
import com.hulk.dryad.admin.mapstruct.SysTenantStruct;
import com.hulk.dryad.common.annotation.Idempotent;
import com.hulk.dryad.common.annotation.OperLog;
import com.hulk.dryad.common.annotation.PrintlnLog;
import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.enums.ActionType;
import com.hulk.dryad.common.constant.enums.BEC;
import com.hulk.dryad.common.constant.enums.DelFlag;
import com.hulk.dryad.manage.provider.cache.SysTenantCache;
import com.hulk.dryad.persistence.entity.SysTenantModel;
import com.hulk.dryad.manage.provider.service.SysTenantService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 租户管理
 *
 * @author kim
 * @date 2019-05-15 15:55:41
 */
@Api(value = "tenant", tags = "租户管理")
@RestController
@RequestMapping("/admin/tenant")
@RequiredArgsConstructor
public class SysTenantController {


	@Value("${dryad.totp.check.enabled:false}")
	private Boolean totpEnable;

	private final  SysTenantService sysTenantService;

	private final SysTenantCache sysTenantCache;

	/**
	 * 分页查询
	 * @param page 分页对象
	 * @param vo 实体
	 * @return page
	 */
	@ApiOperation(value = "getSysTenantPage", notes = "租户分页查询")
	@PrintlnLog
	@GetMapping("/page")
	public R getSysTenantPage(Page page, SysTenantVO vo) {
		SysTenantStruct INSTANCE = SysTenantStruct.INSTANCE;
		SysTenantModel sysTenant = INSTANCE.to(vo);
		Page rpm = sysTenantService.page(page, Wrappers.query(sysTenant));
		Page<SysTenantVO> rpv = INSTANCE.from(rpm);
		return R.ok(rpv);
	}

	/**
	 * 通过id查询租户
	 * @param id ID
	 * @return SysTenantVO
	 */
	@ApiOperation(value = "getById", notes = "通过id查询租户")
	@PrintlnLog
	@GetMapping("/{id}")
	public R getById(@PathVariable("id") Integer id) {
		SysTenantVO sysTenantVO = SysTenantStruct.INSTANCE.from(sysTenantService.getById(id));
		return R.ok(sysTenantVO);
	}

	/**
	 * 验证租户名称是否存在
	 * @param name 租户名
	 * @return count
	 */
	@ApiOperation(value = "checkByName", notes = "验证租户名称是否存在")
	@PrintlnLog
	@GetMapping("/name/{name}")
	public R checkByName(@PathVariable String name) {
		int count =sysTenantService.count(Wrappers.<SysTenantModel>lambdaQuery().eq(SysTenantModel::getName,name));
		if(count>0){
			return R.failed(BEC.E_1006,count);
		}
		return R.ok(count);
	}
	/**
	 * 验证租户编码是否存在
	 * @param code 租户编码
	 * @return count
	 */
	@ApiOperation(value = "checkByCode", notes = "验证租户编码是否存在")
	@PrintlnLog
	@GetMapping("/code/{code}")
	public R checkByCode(@PathVariable String code) {
		int count =sysTenantService.count(Wrappers.<SysTenantModel>lambdaQuery().eq(SysTenantModel::getCode,code));
		if(count>0){
			return R.failed(BEC.E_1006,count);
		}
		return R.ok(count);
	}

	/**
	 * 新增租户
	 * @param vo 实体
	 * @return boolean
	 */
	@ApiOperation(value = "save", notes = "新增租户")
	@Idempotent
	@OperLog(value ="新增租户",action = ActionType.ADD)
	@PostMapping
	@PreAuthorize("@pms.hasPermission('admin_systenant_add')")
	public R save(@RequestBody SysTenantVO vo) {
		SysTenantModel model = SysTenantStruct.INSTANCE.to(vo);
		boolean flag = sysTenantCache.save(model);
		return R.ok(flag);
	}

	/**
	 * 修改租户
	 * @param vo 实体
	 * @return boleann
	 */
	@ApiOperation(value = "updateById", notes = "修改租户")
	@Idempotent
	@OperLog(value ="修改租户",action = ActionType.UPDATE)
	@PutMapping
	@PreAuthorize("@pms.hasPermission('admin_systenant_edit')")
	public R updateById(@RequestBody SysTenantVO vo) {
		SysTenantModel model = SysTenantStruct.INSTANCE.to(vo);
		int count =sysTenantService.count(Wrappers.<SysTenantModel>lambdaQuery().eq(SysTenantModel::getDelFlag, DelFlag.N.getValue())
				.and(v-> v.eq(SysTenantModel::getName,model.getName())
						.or().eq(SysTenantModel::getCode,model.getCode())));
		if(count>0){
			return R.failed(BEC.E_1006);
		}
		boolean flag = 	sysTenantCache.updateById(model);
		return R.ok(flag);
	}

	/**
	 * 通过id删除租户
	 * @param id ID
	 * @return boolean
	 */
	@ApiOperation(value = "removeById", notes = "通过id删除租户")
	@OperLog(value ="删除租户",action = ActionType.DEL)
	@DeleteMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('admin_systenant_del')")
	public R removeById(@PathVariable Integer id) {
		boolean flag = sysTenantCache.removeById(id);
		return R.ok(flag);
	}

	/**
	 * 查询全部有效的租户
	 * @return list
	 */
	@ApiOperation(value = "list", notes = "查询全部有效的租户")
	@PrintlnLog
	@GetMapping("/list")
	public R list() {
		List<SysTenantModel> tenants = sysTenantService.getNormalTenant().stream()
				.filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now()))
				.filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())).collect(Collectors.toList());
		List<SysTenantVO>  vo =	SysTenantStruct.INSTANCE.from(tenants);
		vo.forEach(v->v.setTotpEnable(totpEnable));
		return R.ok(vo);
	}

}
